#include "srv.h"

/*
 *  Ejemplo de servidor que tiene el "sí fácil" para con su
 *  cliente y no se lleva bien con los demás servidores.
 *
 */

void servidor(int mi_cliente)
{
    MPI_Status status; int origen, tag;
    int hay_pedido_local = FALSE;
    int listo_para_salir = FALSE;
    int nro_seq_recibido;
    
    while( ! listo_para_salir ) {
        
        MPI_Recv(&nro_seq_recibido, 1, MPI_INT, ANY_SOURCE, ANY_TAG, COMM_WORLD, &status);
        origen = status.MPI_SOURCE;
        tag = status.MPI_TAG;
        
        if(origen == mi_cliente){
			if (tag == TAG_PEDIDO) {
				pedir_mutex = 1;
				our_sn = highest+1;
				reply_pending = n-1;
				for(int j=0; j< n; j+=2){
					if(j!=mi_cliente){
						 //~ int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
						MPI_Send(NULL, 0, MPI_INT, j, TAG_REQUEST, COMM_WORLD);
						//~ MPI_Send(REQUEST(our_sn,me),j);
					}
				}
				
				
				while(reply_pending != 0){
					MPI_Recv(NULL, 0, MPI_INT, ANY_SOURCE, ANY_TAG, COMM_WORLD, &status);
					origen = status.MPI_SOURCE;
					tag = status.MPI_TAG;
					
					if(tag == REPLY){
						reply_pending --;
					}else{
						// recibiste un request
						Highest = max(Highest, k);
						//recibo por parametro a k y j
						defer = pedir_mutex && ((k>our_sn) || (k==our_sn && j>me));
						if(defer){
							reply_deferred[j] = 1;
						}else{
							//envio mensaje reply
							//~ MPI_Send(REPLY,j);
							MPI_Ibsend(REPLY,j);
						}	
					}
				}
				
				
				assert(origen == mi_cliente);
				debug("Mi cliente solicita acceso exclusivo");
				assert(hay_pedido_local == FALSE);
				hay_pedido_local = TRUE;
				debug("Dándole permiso (frutesco por ahora)");
				MPI_Send(NULL, 0, MPI_INT, mi_cliente, TAG_OTORGADO, COMM_WORLD);
			}
			
			else if (tag == TAG_LIBERO) {
				for(int i=0; i< n; i++){
					if(reply_deferred[j]){
						reply_deferred[j]=0;
						// ------------------------
						MPI_Send(REPLY,j);
					}
				}
				assert(origen == mi_cliente);
				debug("Mi cliente libera su acceso exclusivo");
				assert(hay_pedido_local == TRUE);
				hay_pedido_local = FALSE;
			}
			
			else if (tag == TAG_TERMINE) {
				assert(origen == mi_cliente);
				debug("Mi cliente avisa que terminó");
				listo_para_salir = TRUE;
			}
		}else{
			
			///recibi del servidor
			
			if(tag == TAG_REQUEST){
				// recibiste un request
				Highest =  max(Highest, k);
				//recibo por parametro a k y j
				defer = pedir_mutex && ((k>our_sn) || (k==our_sn && j>me));
				if(defer){
					reply_deferred[j] = 1;
				}else{
					//envio mensaje reply
					MPI_Send(REPLY,j);
				}
			}else{
				// recibiste un reply
				
			}		
		}
		
    
}

